<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者，助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件，未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
declare (strict_types=1);

namespace app\services\yny;

use app\services\BaseServices;
use app\dao\user\UserDao;
use EasyWeChat\Foundation\ServiceProviders\PaymentServiceProvider;
use Redis;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\facade\Db;
use think\facade\Log;
use app\services\car\BaseLogServices;
use app\api\controller\v3\WxPayController;
use crmeb\services\app\MiniProgramService;//CarOrderRefundServices
use app\services\car\CarOrderRefundServices;
use app\model\car\CarOrder;
class YnyServices extends BaseServices
{

    /**
     * YnyServices constructor.
     * @param UserDao $dao
     */
    public function __construct(UserDao $dao)
    {
        $this->dao = $dao;
    }


    /**
     * 执行监视约你游redis修改用户信息
     * @param array $where
     * @return array
     */
    public function ynyredis()
    {
        $redis = new Redis();
        $redis->connect('localhost', 6379);
        try {
            $redis->subscribe(['haha'], function ($redis, $channel, $message) {
                if($message){
                    Db::table('ux_test')->where('id', 2)->update(['q' => $message]);
                }
            });
        } catch (\Throwable $e) {
            Log::error('执行监视约你游redis修改用户信息失败,失败原因:' . $e->getMessage(), $e->getTrace());
        }
        return true;
    }

    /**
     * 退车辆押金
     * @param array $where
     * @return array
     */
    public function tui_car_fee()
    {
        $where = [
            ['o.mchid','<>',""],
            ['o.pay_time','<>',""],
            ['r.tui_car_fee_time','<',time()]
        ];
        try {
            //查询所有已还车待退款的订单
            $data = Db::name('car_order')
                ->alias('o')
                ->field('o.*,r.tui_car_fee_time,r.ss_car_price,r.ss_car_array,r.over_hour,r.over_day,r.over_car_fee,r.refund_fee,r.over_car_fee,r.before_day')
                ->join('car_order_return r','r.id = o.return_id')
                ->where(['o.it_deposit'=>0,'o.status'=>30])
                ->where($where)
                ->where('r.tui_car_fee_time','>',0)
                ->select()->toArray();
            $time = time();
            $cg = 0;
            $sb = 0;
            if($data) foreach($data as $k => $v){
                if($v['tui_car_fee_time']<$time){
                    //完成还车直接退还用户车辆押金
                    $tui = bcsub($v['deposit'],$v['ss_car_price'],2);//记录用
                    $tui_fee = $v['deposit'];//车辆押金
                    if($v['ss_car_price']>0){//如果有车损就减去车损退
                        $tui_fee = bcsub($tui_fee,$v['ss_car_price'],2);//车辆押金-车损
                    }
                    if($v['over_car_fee']>0){//如果有超时费就减去超时费退
                        $tui_fee = bcsub($tui_fee,$v['over_car_fee'],2);//-超时费
                    }
                    if($v['refund_fee']>0&&$v['before_day']>0){//如果是提前还车
                        $tui_fee = bcadd($tui_fee,$v['refund_fee'],2);//+提前还车费
                    }
                    $k_amount = bcadd($v['ss_car_price'],$v['over_car_fee'],2);//扣费总金额 车损费+超时费
                    $tui = $tui_fee;
                    if($tui<=0)$tui = 0;//如果赔付金额小于或等于0，就不退押金了
                    if($tui>0){
                        $tui_fee = $tui_fee*100;
                        $totalFee = $v['price']*100;//订单总金额
                        $out_refund_no = "deposit".$v['order_no'];//系统内部退款订单号，这里用deposit标识是车辆押金加上订单号
                        $wxpay = new WxPayController();
                        if($v['mchid']=='1463846202'){
                            $refundData = [
                                'pay_price'=>$v['price'],//订单总价
                                'refund_price'=>$tui,//要退的钱
                                'refund_no'=>$out_refund_no,//退款单号
                                'type'=>'trade_no',//退款类型
                                'refund_id'=>$out_refund_no,//这才是真正的退款单号
                                'order_id'=>$v['id']
                            ];
                            $ok2 = MiniProgramService::payOrderRefund2($v['out_trade_no'], $refundData);//小程序
                            if($ok2->return_code=="SUCCESS"&&$ok2->return_msg=="OK"){
                                $ok2['code']  = 1;
                            }
                        }else{
                            $ok2 = $wxpay->wx_refund($v['out_trade_no'],0,$totalFee,$tui_fee,0,0,0,$out_refund_no);
                        }
                        if($ok2['code']==1){
                            Db::name('car_order')->where('id',$v['id'])->update(['it_deposit'=>1]);
//                            $tui_fee = $tui_fee/100;
                            $t = $v['deposit']-$k_amount;
                            $msg = $v['order_no'].'订单用户进行还车，退车辆押金'.$t."元,";
                            if($v['refund_fee']>0){
                                $msg =$msg ."提前还车退还费用：".$v['refund_fee'].",";
                            }
                            if($v['over_car_fee']>0){
                                $msg = $msg ."逾期扣款：".$v['over_car_fee'].",";
                            }
                            if($v['ss_car_price']>0){
                                $msg = $msg."车损扣款：".$v['ss_car_price'].",";
                            }
                            $msg = $msg."退费总金额：".$tui;
                            $msg2 = "车损费用：".$v['ss_car_price']."，超时费：".$v['over_car_fee']."，提前还车退还费用：".$v['refund_fee'];
                            BaseLogServices::addLog($v['id'],2,$msg,4,0,"定时任务",28);
                            BaseLogServices::add_deposit_Log($v['id'],$v['order_no'],1,$v['deposit'],$tui,$k_amount,$msg2,$v['store_id'],$v['ss_car_price'],$v['over_car_fee']);
                            //新增订单流水  退车辆押金流水 2024年2月25日16:31:11
                            BaseLogServices::add_order_deposit_flow('car',$v,$msg,$t);
                            $cg++;
                        }else{
                            BaseLogServices::add_deposit_error($v['id'],$ok2['msg'],'car');
                            $sb++;
                            continue;
                        }
                    }else{
                        Db::name('car_order')->where('id',$v['id'])->update(['it_deposit'=>1]);
                        $msg = $v['order_no'].'押金全部扣除'."，总共扣款违章押金共：".$k_amount."元";
                        BaseLogServices::addLog($v['id'],2,$msg,4,0,"定时任务",28);
                        BaseLogServices::add_deposit_Log($v['id'],$v['order_no'],1,$v['deposit'],$tui,$k_amount,"用户还车时车损或超时费累计总和大于或等于押金，押金全部扣除",$v['store_id'],$v['ss_car_price'],$v['over_car_fee']);
                        //新增订单流水  退车辆押金流水 2024年2月25日16:31:11
                        BaseLogServices::add_order_deposit_flow('car',$v,$msg,$k_amount);
                    }

                }
            }

        } catch (\Throwable $e) {
            Log::error('车辆押金退款失败,失败原因:' . $e->getMessage(), $e->getTrace());
        }
        echo "定时任务《车辆押金》运行成功，成功：".$cg.'条，失败：'.$sb."条\n";
//        return true;
    }

    /**
     * 退违章押金
     * @param array $where
     * @return array
     */
    public function tui_wz_fee()
    {
        $where = [
            ['o.mchid','<>',""],
            ['r.tui_wz_fee_time','<',time()]
        ];
        try {
            //查询所有已还车待退款的订单
            $data = Db::name('car_order')
                ->alias('o')
                ->field('o.*,r.tui_wz_fee_time,r.ss_car_price')
                ->join('car_order_return r','r.id = o.return_id','left')
                ->where(['o.it_deposit'=>1,'o.status'=>30,'it_illegal_deposit'=>0])
                ->where($where)
                ->where('r.tui_wz_fee_time','>',0)
                ->select()->toArray();
            $time = time();
            $cg = 0;
            $sb = 0;
            if($data) foreach($data as $k => $v){
                if($v['tui_wz_fee_time']<$time){
                    $k_deposit = Db::name('car_wz')->where(['illegal_return_type'=>3,'status'=>1,'order_id'=>$v['id']])->sum('amount');//未处理的违章计算出总扣款的钱
                    $tui_fee = ($v['illegal_deposit']-$k_deposit)*100;//违章押金  退款用
                    $tui = $v['illegal_deposit']-$k_deposit;//需要退款金额 记录用
                    if($tui<=0)$tui = 0;//如果违章金额小于或等于0，就不退押金了
                    if($tui>0){
                        $totalFee = $v['price']*100;//订单总金额
                        $out_refund_no = "wz_deposit".$v['order_no'];//系统内部退款订单号，这里用deposit标识是车辆押金加上订单号
                        $wxpay = new WxPayController();
                        if($v['mchid']=='1463846202'){
                            $refundData = [
                                'pay_price'=>$v['price'],//订单总价
                                'refund_price'=>$tui,//要退的钱
                                'refund_no'=>$out_refund_no,//退款单号
                                'type'=>'trade_no',//退款类型
                                'refund_id'=>$out_refund_no,//这才是真正的退款单号
                                'order_id'=>$v['id']
                            ];
                            $ok2 = MiniProgramService::payOrderRefund2($v['out_trade_no'], $refundData);//小程序
                            if($ok2->return_code=="SUCCESS"&&$ok2->return_msg=="OK"){
                                $ok2['code']  = 1;
                            }
                        }else{
                            $ok2 = $wxpay->wx_refund($v['out_trade_no'],0,$totalFee,$tui_fee,0,0,0,$out_refund_no);
                        }
                        if($ok2['code']==1){
                            Db::name('car_order')->where('id',$v['id'])->update(['it_illegal_deposit'=>1,'status'=>40]);
                            Db::name('car_wz')->where(['illegal_return_type'=>3,'status'=>1,'order_id'=>$v['id']])->update(['illegal_return_type'=>0,'status'=>3,'wz_ok_time'=>time()]);
                            $msg = $v['order_no'].'用户还车15天后，自动退还违章押金'.$tui."元,"."违章押金扣款：".$k_deposit."元";
                            BaseLogServices::addLog($v['id'],2,$msg,4,0,"定时任务",29);
                            BaseLogServices::add_deposit_Log($v['id'],$v['order_no'],2,$v['illegal_deposit'],$tui,$k_deposit,$msg,$v['store_id'],0,$k_deposit);
                            //新增订单流水  退违章押金流水 2024年2月25日16:48:08
                            BaseLogServices::add_order_deposit_flow('wz',$v,$msg,$tui);

                            $cg++;
                        }else{
                            BaseLogServices::add_deposit_error($v['id'],$ok2['msg'],'wz');
                            $sb++;
                            continue;
                        }
                    }else{
                        Db::name('car_order')->where('id',$v['id'])->update(['it_illegal_deposit'=>1,'status'=>40]);
                        Db::name('car_wz')->where(['illegal_return_type'=>3,'status'=>1,'order_id'=>$v['id']])->update(['illegal_return_type'=>0,'status'=>3,'wz_ok_time'=>time()]);
                        $msg = $v['order_no'].'用户超时15天未处理违章，押金全部扣除'."，总共扣款违章押金共：".$k_deposit."元";
                        BaseLogServices::addLog($v['id'],2,$msg,4,0,"定时任务",29);
                        BaseLogServices::add_deposit_Log($v['id'],$v['order_no'],2,$v['illegal_deposit'],$tui,$k_deposit,"用户超时15天未处理违章，押金全部扣除",$v['store_id'],0,$k_deposit);
                        //新增订单流水  退违章押金流水 2024年2月25日16:48:08
                        BaseLogServices::add_order_deposit_flow('wz',$v,$msg,$k_deposit);
                    }

                }
            }

        } catch (\Throwable $e) {
            Log::error('违章押金退款失败,失败原因:' . $e->getMessage(), $e->getTrace());
        }
        echo "定时任务《违章押金》运行成功，成功：".$cg.'条，失败：'.$sb."条\n";
    }

    //取消订单T+1退款
    public function tui_qx_price(){
        $where = [
            ['r.tui_price_time','<>',""],
            ['r.tui_price_time','<',time()],
            ['o.status','=',10],
            ['r.status','=',10]
        ];
        try {
            //查询所有已还车待退款的订单
            $data = Db::name('car_order_refund')
                ->alias('r')
                ->field('r.*,o.status,o.order_no')
                ->join('car_order o','o.id = r.order_id','left')
                ->where($where)
                ->where('r.tui_price_time','>',0)
                ->select()->toArray();
            $time = time();
            $cg = 0;
            $sb = 0;
            if($data) foreach($data as $k => $v){
                if($v['tui_price_time']<$time){
                    $tui = $v['price'];//需要退款金额 记录用
                    if($tui<=0)$tui = 0;//如果违章金额小于或等于0，就不退押金了
                    if($tui>0){
                        /** @var CarOrderRefundServices $refundServices */
                        $refundServices = app()->make(CarOrderRefundServices::class);
                        $orderInfo = CarOrder::where('id', $v['order_id'])->find();
                        $ok2 = $refundServices->payOrderRefund($orderInfo, $v);  //直接退款
                        if($ok2['code']==1){
                            $beizhu = $v['remark']."退款成功".",取消订单服务费扣费：".$v['deduct_price'];
                            BaseLogServices::addLog($orderInfo['id'],2,$beizhu, 4, 0, "定时任务", 2);
                            //新增订单流水  取消订单流水 2024年2月25日16:48:08
                            BaseLogServices::add_order_deposit_flow('quxiao',$orderInfo,$beizhu,$tui);
                            $cg++;
                        }else{
                            BaseLogServices::add_deposit_error($v['order_id'],$ok2['msg'],'qx_price');
                            $sb++;
                            continue;
                        }
                    }
                }
            }
        } catch (\Throwable $e) {
            Log::error('取消订单退款失败,失败原因:' . $e->getMessage(), $e->getTrace());
        }
        echo "定时任务《取消订单退款》T+1运行成功，成功：".$cg.'条，失败：'.$sb."条\n";
    }

}
